use model_graph_channel::http_request as remote_http_request;
use model_graph_common::transport::http::http_post;
use model_graph_types::{
    assistant::{
        chat::{ChatMessage, ChatOptions, ChatProvider},
        tts::{TtsRequestMessage, TtsRequestOptions, TtsResponseMessage},
    },
    channel::{HttpRequest, HttpResponse},
};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

pub async fn sv2tts_request(
    provider: ChatProvider,
    request: TtsRequestMessage,
    options: TtsRequestOptions,
) -> anyhow::Result<TtsResponseMessage> {
    tracing::debug!("请求sv2tts接口:{:?}", provider);
    let url = &provider.url;
    let token_key = &provider.token_key;
    let token = &provider.token;

    let mut headers = HashMap::new();
    headers.insert(
        String::from("Content-Type"),
        String::from("application/json"),
    );

    //TOKEN
    if let Some(token) = token {
        //
        if let Some(token_key) = token_key {
            headers.insert(token_key.clone(), token.clone());
        } else {
            headers.insert(String::from("Authorization"), token.clone());
        }
    }

    let default_body = serde_json::to_string(&serde_json::json!({
        "refer_wav_path": request.prompt_audio_path.map_or(String::new(), |a|a),
        "prompt_text": request.prompt_text.map_or(String::new(), |a|a),
        "prompt_language":  request.prompt_language.map_or(String::from("zh"), |a|a),
        "text":  request.text,
        "text_language":request.text_language.map_or(String::from("zh"), |a|a),
    }))?;

    let body = if let Some(request_jmespath) = &provider.request_jmespath {
        let messages_value = if request_jmespath != "" {
            //
            // let expr = jmespath::compile(request_jmespath.as_str())?;
            // let result = expr.search(serde_json::json!({
            //     "messages": messages
            // }))?;
            default_body
        } else {
            default_body
        };
        messages_value
    } else {
        default_body
    };

    //
    let response = if let Some(peer) = &provider.peer {
        tracing::debug!("调用节点sv2tts服务:{}", peer);
        //调用节点
        let request: HttpRequest =
            HttpRequest::post(url.clone(), headers, Some(body.into_bytes()))?;
        //一小时超时
        let response_result = remote_http_request(&peer.clone(), request, 3600000).await;
        match response_result {
            Ok(response) => {
                if response.status == 200 {
                    tracing::debug!("请求成功:{:?}", response.body.len());
                    Ok(response.body)
                } else {
                    Err(anyhow::anyhow!("请求失败!"))
                }
            }
            Err(err) => Err(anyhow::anyhow!("请求失败!{}", err)),
        }
    } else {
        //直接本地请求
        let response_result = http_post(url, &headers, body.into_bytes()).await;
        match response_result {
            Ok((_, _, response)) => Ok(response),
            Err(err) => Err(anyhow::anyhow!("请求失败!{}", err)),
        }
    };
    match response {
        Ok(response) => {
            tracing::debug!("返回的数据:{}", response.len());

            return Ok(TtsResponseMessage::new(response)?);
        }
        Err(err) => Err(anyhow::anyhow!("抱歉!{}", err)),
    }
}

pub async fn tts_request(
    provider: ChatProvider,
    request: TtsRequestMessage,
    options: TtsRequestOptions,
) -> anyhow::Result<TtsResponseMessage> {
    tracing::debug!("请求tts接口:{:?}", provider);
    let url = &provider.url;
    let token_key = &provider.token_key;
    let token = &provider.token;

    let mut headers = HashMap::new();
    headers.insert(
        String::from("Content-Type"),
        String::from("application/json"),
    );

    //TOKEN
    if let Some(token) = token {
        //
        if let Some(token_key) = token_key {
            headers.insert(token_key.clone(), token.clone());
        } else {
            headers.insert(String::from("Authorization"), token.clone());
        }
    }

    let default_body = serde_json::to_string(&serde_json::json!({
        "refer_wav_path": request.prompt_audio_path.map_or(String::new(), |a|a),
        "prompt_text": request.prompt_text.map_or(String::new(), |a|a),
        "prompt_language":  request.prompt_language.map_or(String::from("zh"), |a|a),
        "text":  request.text,
        "text_language":request.text_language.map_or(String::from("zh"), |a|a),
    }))?;

    let body = if let Some(request_jmespath) = &provider.request_jmespath {
        let messages_value = if request_jmespath != "" {
            //
            // let expr = jmespath::compile(request_jmespath.as_str())?;
            // let result = expr.search(serde_json::json!({
            //     "messages": messages
            // }))?;
            default_body
        } else {
            default_body
        };
        messages_value
    } else {
        default_body
    };

    Err(anyhow::anyhow!(""))
}

fn _get_model(provider: &ChatProvider, options: &ChatOptions) -> anyhow::Result<String> {
    if let Some(model) = &options.model {
        return Ok(model.clone());
    }

    if let Some(model) = provider.options.get("model") {
        return Ok(model.clone());
    }

    Ok(String::from("gpt-3.5-turbo"))
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
struct OpenAIChoice {
    pub index: Option<i32>,
    pub message: ChatMessage,
    pub finish_reason: Option<String>,
}

#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
struct OpenAIChatResponse {
    pub choices: Vec<OpenAIChoice>,
}
